#ifndef _INV_MPU_H_
#define _INV_MPU_H_

#include <stdint.h>

// MPU chip types
#define INV_MPU6050       0x68
#define INV_MPU6500       0x70
#define INV_MPU9150       0x68
#define INV_MPU9250       0x71
#define INV_ICM20608      0xAF
#define INV_ICM20602      0x12

// MPU configuration structure
struct int_param_s {
    void (*cb)(void);
    unsigned short pin;
    unsigned char lp_exit;
    unsigned char active_low;
};

// Clock source options
#define INV_CLK_INTERNAL    0x00
#define INV_CLK_PLL         0x01

// Low power accel rate options
#define INV_LPA_1_25HZ      0x00
#define INV_LPA_5HZ         0x01
#define INV_LPA_20HZ        0x02
#define INV_LPA_40HZ        0x03

// Function prototypes
int mpu_init(struct int_param_s *int_param);
int mpu_set_bypass(unsigned char bypass_on);
int mpu_set_sensors(unsigned char sensors);
int mpu_set_gyro_fsr(unsigned short fsr);
int mpu_set_accel_fsr(unsigned char fsr);
int mpu_set_lpf(unsigned short lpf);
int mpu_set_sample_rate(unsigned short rate);
int mpu_get_sample_rate(unsigned short *rate);
int mpu_get_gyro_fsr(unsigned short *fsr);
int mpu_get_accel_fsr(unsigned char *fsr);
int mpu_get_lpf(unsigned short *lpf);
int mpu_get_gyro_sens(float *sens);
int mpu_get_accel_sens(float *sens);
int mpu_get_int_status(short *status);
int mpu_read_fifo(short *gyro, short *accel, unsigned long *timestamp, unsigned char *sensors, unsigned char *more);
int mpu_read_fifo_stream(unsigned short length, unsigned char *data, unsigned char *more);
int mpu_reset_fifo(void);
int mpu_get_power_state(unsigned char *power_on);
int mpu_set_fifo_rate(unsigned short rate);
int mpu_get_fifo_rate(unsigned short *rate);
int mpu_get_fifo_config(unsigned char *sensors);
int mpu_configure_fifo(unsigned char sensors);
int mpu_get_gyro_reg(short *data, unsigned long *timestamp);
int mpu_get_accel_reg(short *data, unsigned long *timestamp);
int mpu_get_compass_reg(short *data, unsigned long *timestamp);
int mpu_get_temperature(long *data, unsigned long *timestamp);
int mpu_self_test(long *gyro, long *accel);
int mpu_register_tap_cb(void (*func)(unsigned char, unsigned char));
int mpu_set_dmp_state(unsigned char enable);
int mpu_get_dmp_state(unsigned char *enabled);

// Sensor bitmasks
#define INV_X_GYRO      (0x40)
#define INV_Y_GYRO      (0x20)
#define INV_Z_GYRO      (0x10)
#define INV_XYZ_GYRO    (INV_X_GYRO | INV_Y_GYRO | INV_Z_GYRO)
#define INV_XYZ_ACCEL   (0x08)
#define INV_XYZ_COMPASS (0x01)

// Hardware registers
#define MPUREG_WHO_AM_I         0x75
#define MPUREG_SMPLRT_DIV       0x19
#define MPUREG_CONFIG           0x1A
#define MPUREG_GYRO_CONFIG      0x1B
#define MPUREG_ACCEL_CONFIG     0x1C
#define MPUREG_ACCEL_CONFIG2    0x1D
#define MPUREG_LP_ACCEL_ODR     0x1E
#define MPUREG_WOM_THR          0x1F
#define MPUREG_FIFO_EN          0x23
#define MPUREG_I2C_MST_CTRL     0x24
#define MPUREG_I2C_SLV0_ADDR    0x25
#define MPUREG_I2C_SLV0_REG     0x26
#define MPUREG_I2C_SLV0_CTRL    0x27
#define MPUREG_I2C_SLV1_ADDR    0x28
#define MPUREG_I2C_SLV1_REG     0x29
#define MPUREG_I2C_SLV1_CTRL    0x2A
#define MPUREG_I2C_SLV2_ADDR    0x2B
#define MPUREG_I2C_SLV2_REG     0x2C
#define MPUREG_I2C_SLV2_CTRL    0x2D
#define MPUREG_I2C_SLV3_ADDR    0x2E
#define MPUREG_I2C_SLV3_REG     0x2F
#define MPUREG_I2C_SLV3_CTRL    0x30
#define MPUREG_I2C_SLV4_ADDR    0x31
#define MPUREG_I2C_SLV4_REG     0x32
#define MPUREG_I2C_SLV4_DO      0x33
#define MPUREG_I2C_SLV4_CTRL    0x34
#define MPUREG_I2C_SLV4_DI      0x35
#define MPUREG_I2C_MST_STATUS   0x36
#define MPUREG_INT_PIN_CFG      0x37
#define MPUREG_INT_ENABLE       0x38
#define MPUREG_DMP_INT_STATUS   0x39
#define MPUREG_INT_STATUS       0x3A
#define MPUREG_ACCEL_XOUT_H     0x3B
#define MPUREG_ACCEL_XOUT_L     0x3C
#define MPUREG_ACCEL_YOUT_H     0x3D
#define MPUREG_ACCEL_YOUT_L     0x3E
#define MPUREG_ACCEL_ZOUT_H     0x3F
#define MPUREG_ACCEL_ZOUT_L     0x40
#define MPUREG_TEMP_OUT_H       0x41
#define MPUREG_TEMP_OUT_L       0x42
#define MPUREG_GYRO_XOUT_H      0x43
#define MPUREG_GYRO_XOUT_L      0x44
#define MPUREG_GYRO_YOUT_H      0x45
#define MPUREG_GYRO_YOUT_L      0x46
#define MPUREG_GYRO_ZOUT_H      0x47
#define MPUREG_GYRO_ZOUT_L      0x48

#endif  /* _INV_MPU_H_ */
